﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

namespace Titan.Remoting
{
    public class IDCChannel : IChannel, IChannelSender, IChannelReceiver
    {
        private ChannelDataStore _channelData;
        private Dictionary<string, object> _singletons;
        private string _searchPath;
        private bool _dynamicLoad;

        public IDCChannel()
        {
            _channelData = new ChannelDataStore(new string[] { "idc://" });
            _singletons = new Dictionary<string, object>(StringComparer.CurrentCultureIgnoreCase);
            _dynamicLoad = false;
        }

        public IDCChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider)
            : this()
        {
            if (null != properties)
            {
                foreach (DictionaryEntry entry in properties)
                {
                    switch (entry.Key.ToString())
                    {
                        case "searchPath":
                            SearchPath = Convert.ToString(entry.Value).Trim();
                            break;
                        case "dynamicLoad":
                            DynamicLoad = Convert.ToBoolean(entry.Value.ToString());
                            break;
                    }
                }
            }
        }

        public string SearchPath
        {
            get { return _searchPath; }
            set { _searchPath = value; }
        }

        public bool DynamicLoad
        {
            get { return _dynamicLoad; }
            set { _dynamicLoad = value; }
        }

        internal Dictionary<string, object> Singletons
        {
            get { return _singletons; }
        }

        public string ChannelName
        {
            get { return "idc"; }
        }

        public int ChannelPriority
        {
            get { return 1; }
        }

        public string Parse(string url, out string objectURI)
        {
            string lowerUrl = url.ToLower();
            if (lowerUrl.StartsWith("idc://", StringComparison.Ordinal))
            {
                objectURI = lowerUrl.Substring("idc://".Length);
                return "idc://";
            }
            else
            {
                objectURI = null;
                return null;
            }
        }

        public IMessageSink CreateMessageSink(string url, object remoteChannelData, out string objectURI)
        {
            if (url.ToLower().StartsWith("idc://", StringComparison.Ordinal))
            {
                objectURI = url.Substring("idc://".Length);
                return new IDCMessageSink(this, remoteChannelData, objectURI);
            }
            else
            {
                objectURI = null;
                return null;
            }
        }

        public object ChannelData
        {
            get { return _channelData; }
        }

        public string[] GetUrlsForUri(string objectURI)
        {
            if (objectURI.StartsWith("/", StringComparison.Ordinal))
            {
                objectURI = objectURI.Substring(1);
            }
            return new string[] { "idc://" + objectURI };
        }

        public void StartListening(object data)
        {
        }

        public void StopListening(object data)
        {
            lock (_singletons)
                _singletons.Clear();
        }
    }
}
